/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "cj_ability.h"

#include <dlfcn.h>
#include <regex>
#include <cstdlib>

#include "hilog.h"
#include "cj_runtime.h"
#include "cj_ability_object.h"
#include "window_view_adapter.h"

namespace Keels {
namespace AbilityRuntime {
namespace Platform {
namespace {
sptr<Keels::Rosen::CJWindowStageImpl> CreateCJWindowStage(std::shared_ptr<Rosen::WindowStage> windowStage)
{
    auto id = OHOS_CreateCJWindowStage(windowStage);
    return Keels::FFI::FFIData::GetData<Keels::Rosen::CJWindowStageImpl>(id);
}
} // namespace

std::shared_ptr<Ability> CJAbility::Create(const std::unique_ptr<Runtime>& runtime)
{
    return std::make_shared<CJAbility>(static_cast<CJRuntime&>(*runtime));
}

CJAbility::CJAbility(CJRuntime& cjRuntime) : cjRuntime_(cjRuntime)
{
}

void CJAbility::Init(const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
{
    HILOG_DEBUG("CJAbility::Init");
    if (!abilityInfo) {
        HILOG_ERROR("abilityInfo is nullptr");
        return;
    }

    Ability::Init(abilityInfo);
    cjAbilityObj_ = CJAbilityObject::LoadModule(abilityInfo->name);
    if (cjAbilityObj_ == nullptr) {
        HILOG_ERROR("Failed to get CJAbility object");
        return;
    }
    cjAbilityObj_->Init(this);
}

void CJAbility::OnCreate(const Want& want)
{
    HILOG_DEBUG("CJAbility::OnCreate ability name:%{public}s", GetAbilityName().c_str());
    Ability::OnCreate(want);
    if (!cjAbilityObj_) {
        HILOG_ERROR("null cjAbilityObj");
        return;
    }
    cjAbilityObj_->OnCreate(want, GetLaunchParam());
}

void CJAbility::OnForeground(const Want& want)
{
    HILOG_DEBUG("CJAbility::OnForeground ability name:%{public}s", GetAbilityName().c_str());

    Ability::OnForeground(want);

    if (!cjAbilityObj_) {
        HILOG_ERROR("null cjAbilityObj");
        return;
    }

    cjAbilityObj_->OnForeground(want);
}

void CJAbility::OnWindowStageCreated()
{
    HILOG_DEBUG("CJAbility::OnWindowStageCreated, ability name:%{public}s", GetAbilityName().c_str());
    Ability::OnWindowStageCreated();

    cjWindowStage_ = CreateCJWindowStage(windowStage_);
    if (!cjWindowStage_) {
        HILOG_ERROR("create CJWindowStage object failed");
        return;
    }
    cjAbilityObj_->OnWindowStageCreated(cjWindowStage_.GetRefPtr());
}

void CJAbility::OnWindowStageDestroy() {
    HILOG_DEBUG("CJAbility::OnWindowStageDestroy, ability name:%{public}s", GetAbilityName().c_str());
    Ability::OnWindowStageDestroy();
}

void CJAbility::OnDestroy() {
    HILOG_DEBUG("CJAbility::OnDestroy, ability name:%{public}s", GetAbilityName().c_str());
    Ability::OnDestroy();
}
} // namespace Platform
} // namespace AbilityRuntime
} // namespace Keels